/**
 * 验证服务器有效性
 */
const config = require('../config')
const sha1 = require('sha1')
const { getUserDataAsync, parseXMLAsync, formatJSData } = require('../utils/tool')
const template = require('./template')
const reply = require('./reply')

module.exports = () => {
    return async (req, res, next) => {
        /**
         * 微信加密签名：将三个参数（timestamp，nonce，token）按字典序组合成数组，再拼成字符串，进行sha1加密，生成一个signature
         * 如果对比后一样，返回echostr给微信服务器
        {
            signature: '58a81a27d7211f7788d7bdb81ad333b8019952ed',  // 加密签名
            echostr: '9120363192641772507',  // 随机字符串
            timestamp: '1586600083',         // 发送请求的时间戳
            nonce: '409615842'               // 随机数字
        }
        */
        const { signature, echostr, timestamp, nonce } = req.query
        const { token } = config

        const sha1Str = sha1([timestamp, nonce, token].sort().join(''))
        /**
         * 微信服务器GET验证 POST传数据
         */
        if(req.method === 'GET') {
            if(sha1Str === signature) {
                res.send(echostr)
            }else {
                res.end('error')
            }
        }else if(req.method === 'POST') {
            // 验证消息不来自微信服务器
            if(sha1Str !== signature) {
                res.end('error')
            }
            // 微信请求体中为流式数据
            const xmlData = await getUserDataAsync(req)
            /**
            <xml>
                <ToUserName><![CDATA[gh_48d9033a6d2a]]></ToUserName>                   // 开发者id
                <FromUserName><![CDATA[oGhgU1K8J-8v5g9_isu2gK7UhMXM]]></FromUserName>  // 用户openid
                <CreateTime>1586685066</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[456]]></Content>
                <MsgId>22715870743733721</MsgId>                                       // 消息id，微信服务器保存三天
            </xml>
            */
            const jsData = await parseXMLAsync(xmlData)
            const message = formatJSData(jsData)
            
            const options = reply(message)
            const replyMessage = template(options)
            res.send(replyMessage)
        }else {
            res.end('error')
        }
    }
}